From d5cbf3ec5835084badcad2e36d03fb4b30478e08 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Mon, 12 Mar 2007 13:53:43 +0000 Subject: [PATCH] x86: Add VGCF_onlien flag to vcpu_guest_context. Change common Xen code to start all VCPUs (except idle ones) offline. Change arch code to deal with this. Signed-off-by: Keir Fraser --- tools/libxc/xc_dom_x86.c | 4 ++-- tools/libxc/xc_hvm_build.c | 8 +++++++- tools/libxc/xc_linux_restore.c | 5 +++++ xen/arch/ia64/xen/domain.c | 8 ++++++-- xen/arch/powerpc/domain.c | 5 ++++- xen/arch/powerpc/domain_build.c | 1 + xen/arch/x86/domain.c | 7 ++++++- xen/arch/x86/domain_build.c | 1 + xen/common/domain.c | 2 +- xen/common/domctl.c | 18 +++++++----------- xen/include/public/arch-x86/xen.h | 2 ++ xen/include/public/foreign/structs.py | 2 ++ 12 files changed, 44 insertions(+), 19 deletions(-) diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c index 19296daf10..a508775140 100644 --- a/tools/libxc/xc_dom_x86.c +++ b/tools/libxc/xc_dom_x86.c @@ -455,7 +455,7 @@ static int vcpu_x86_32(struct xc_dom_image *dom, void *ptr) ctxt->kernel_ss = ctxt->user_regs.ss; ctxt->kernel_sp = ctxt->user_regs.esp; - ctxt->flags = VGCF_in_kernel_X86_32; + ctxt->flags = VGCF_in_kernel_X86_32 | VGCF_online_X86_32; if ( dom->parms.pae == 2 /* extended_cr3 */ || dom->parms.pae == 3 /* bimodal */ ) ctxt->vm_assist |= (1UL << VMASST_TYPE_pae_extended_cr3); @@ -494,7 +494,7 @@ static int vcpu_x86_64(struct xc_dom_image *dom, void *ptr) ctxt->kernel_ss = ctxt->user_regs.ss; ctxt->kernel_sp = ctxt->user_regs.esp; - ctxt->flags = VGCF_in_kernel_X86_64; + ctxt->flags = VGCF_in_kernel_X86_64 | VGCF_online_X86_64; cr3_pfn = xc_dom_p2m_guest(dom, dom->pgtables_seg.pfn); ctxt->ctrlreg[3] = xen_pfn_to_cr3_x86_64(cr3_pfn); xc_dom_printf("%s: cr3: pfn 0x%" PRIpfn " mfn 0x%" PRIpfn "\n", diff --git a/tools/libxc/xc_hvm_build.c b/tools/libxc/xc_hvm_build.c index 2238d315bc..00f4624501 100644 --- a/tools/libxc/xc_hvm_build.c +++ b/tools/libxc/xc_hvm_build.c @@ -302,9 +302,15 @@ static int setup_guest(int xc_handle, /* Set [er]ip in the way that's right for Xen */ if ( strstr(caps, "x86_64") ) + { ctxt->c64.user_regs.rip = elf_uval(&elf, elf.ehdr, e_entry); + ctxt->c64.flags = VGCF_online; + } else + { ctxt->c32.user_regs.eip = elf_uval(&elf, elf.ehdr, e_entry); + ctxt->c32.flags = VGCF_online; + } return 0; @@ -344,7 +350,7 @@ static int xc_hvm_build_internal(int xc_handle, memset(&launch_domctl, 0, sizeof(launch_domctl)); launch_domctl.domain = (domid_t)domid; - launch_domctl.u.vcpucontext.vcpu = 0; + launch_domctl.u.vcpucontext.vcpu = 0; set_xen_guest_handle(launch_domctl.u.vcpucontext.ctxt, &ctxt.c); launch_domctl.cmd = XEN_DOMCTL_setvcpucontext; rc = xc_domctl(xc_handle, &launch_domctl); diff --git a/tools/libxc/xc_linux_restore.c b/tools/libxc/xc_linux_restore.c index 6fa0388d3f..d3a87262a0 100644 --- a/tools/libxc/xc_linux_restore.c +++ b/tools/libxc/xc_linux_restore.c @@ -189,6 +189,7 @@ int xc_linux_restore(int xc_handle, int io_fd, uint64_t vcpumap = 1ULL; unsigned int max_vcpu_id = 0; + int new_ctxt_format = 0; max_pfn = nr_pfns; @@ -372,6 +373,7 @@ int xc_linux_restore(int xc_handle, int io_fd, } if (j == -2) { + new_ctxt_format = 1; if (!read_exact(io_fd, &max_vcpu_id, sizeof(int)) || (max_vcpu_id >= 64) || !read_exact(io_fd, &vcpumap, sizeof(uint64_t))) { @@ -797,6 +799,9 @@ int xc_linux_restore(int xc_handle, int io_fd, goto out; } + if ( !new_ctxt_format ) + ctxt.flags |= VGCF_online; + if (i == 0) { /* * Uncanonicalise the suspend-record frame number and poke diff --git a/xen/arch/ia64/xen/domain.c b/xen/arch/ia64/xen/domain.c index 631d8dfa09..2bb2ef8172 100644 --- a/xen/arch/ia64/xen/domain.c +++ b/xen/arch/ia64/xen/domain.c @@ -672,8 +672,11 @@ int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_u c) /* This overrides some registers. */ vcpu_init_regs(v); - /* Don't redo final setup */ - set_bit(_VCPUF_initialised, &v->vcpu_flags); + /* Don't redo final setup. Auto-online VCPU0. */ + if (!test_and_set_bit(_VCPUF_initialised, &v->vcpu_flags) && + (v->vcpu_id == 0)) + clear_bit(_VCPUF_down, &v->vcpu_flags); + return 0; } @@ -1182,6 +1185,7 @@ int construct_dom0(struct domain *d, printk("Dom0: 0x%lx\n", (u64)dom0); set_bit(_VCPUF_initialised, &v->vcpu_flags); + clear_bit(_VCPUF_down, &v->vcpu_flags); /* Build firmware. Note: Linux kernel reserve memory used by start_info, so there is diff --git a/xen/arch/powerpc/domain.c b/xen/arch/powerpc/domain.c index 156b70ffd9..1ecf35a666 100644 --- a/xen/arch/powerpc/domain.c +++ b/xen/arch/powerpc/domain.c @@ -168,7 +168,10 @@ int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_u c) d->shared_info->wc_nsec = dom0->shared_info->wc_nsec; d->shared_info->arch.boot_timebase = dom0->shared_info->arch.boot_timebase; - set_bit(_VCPUF_initialised, &v->vcpu_flags); + /* Auto-online VCPU0 when it is initialised. */ + if ( !test_and_set_bit(_VCPUF_initialised, &v->vcpu_flags) && + (v->vcpu_id == 0) ) + clear_bit(_VCPUF_down, &v->vcpu_flags); cpu_init_vcpu(v); diff --git a/xen/arch/powerpc/domain_build.c b/xen/arch/powerpc/domain_build.c index 08d53ff9dc..af7ad3db45 100644 --- a/xen/arch/powerpc/domain_build.c +++ b/xen/arch/powerpc/domain_build.c @@ -274,6 +274,7 @@ int construct_dom0(struct domain *d, ofd_dom0_fixup(d, *ofh_tree + rma, cmdline, shared_info_addr); set_bit(_VCPUF_initialised, &v->vcpu_flags); + clear_bit(_VCPUF_down, &v->vcpu_flags); rc = 0; diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 2d6bdca72c..ca82c12590 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -601,7 +601,7 @@ int arch_set_info_guest( } if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) ) - return 0; + goto out; memset(v->arch.guest_context.debugreg, 0, sizeof(v->arch.guest_context.debugreg)); @@ -706,6 +706,11 @@ int arch_set_info_guest( update_cr3(v); + out: + if ( flags & VGCF_online ) + clear_bit(_VCPUF_down, &v->vcpu_flags); + else + set_bit(_VCPUF_down, &v->vcpu_flags); return 0; #undef c } diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c index 5d7941ab5d..96215da601 100644 --- a/xen/arch/x86/domain_build.c +++ b/xen/arch/x86/domain_build.c @@ -902,6 +902,7 @@ int construct_dom0(struct domain *d, update_domain_wallclock_time(d); set_bit(_VCPUF_initialised, &v->vcpu_flags); + clear_bit(_VCPUF_down, &v->vcpu_flags); /* * Initial register values: diff --git a/xen/common/domain.c b/xen/common/domain.c index 57fb9ade71..3008a4cc90 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -102,7 +102,7 @@ struct vcpu *alloc_vcpu( v->runstate.state = is_idle_vcpu(v) ? RUNSTATE_running : RUNSTATE_offline; v->runstate.state_entry_time = NOW(); - if ( (vcpu_id != 0) && !is_idle_domain(d) ) + if ( !is_idle_domain(d) ) set_bit(_VCPUF_down, &v->vcpu_flags); if ( sched_init_vcpu(v, cpu_id) != 0 ) diff --git a/xen/common/domctl.c b/xen/common/domctl.c index 3a45586d65..6f2f351895 100644 --- a/xen/common/domctl.c +++ b/xen/common/domctl.c @@ -268,18 +268,14 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl) case XEN_DOMCTL_unpausedomain: { struct domain *d = rcu_lock_domain_by_id(op->domain); + ret = -ESRCH; - if ( d != NULL ) - { - ret = -EINVAL; - if ( (d != current->domain) && (d->vcpu[0] != NULL) && - test_bit(_VCPUF_initialised, &d->vcpu[0]->vcpu_flags) ) - { - domain_unpause_by_systemcontroller(d); - ret = 0; - } - rcu_unlock_domain(d); - } + if ( d == NULL ) + break; + + domain_unpause_by_systemcontroller(d); + rcu_unlock_domain(d); + ret = 0; } break; diff --git a/xen/include/public/arch-x86/xen.h b/xen/include/public/arch-x86/xen.h index f927130058..9fe0b76204 100644 --- a/xen/include/public/arch-x86/xen.h +++ b/xen/include/public/arch-x86/xen.h @@ -126,6 +126,8 @@ struct vcpu_guest_context { #define VGCF_failsafe_disables_events (1<<_VGCF_failsafe_disables_events) #define _VGCF_syscall_disables_events 4 #define VGCF_syscall_disables_events (1<<_VGCF_syscall_disables_events) +#define _VGCF_online 5 +#define VGCF_online (1<<_VGCF_online) unsigned long flags; /* VGCF_* flags */ struct cpu_user_regs user_regs; /* User-level CPU registers */ struct trap_info trap_ctxt[256]; /* Virtual IDT */ diff --git a/xen/include/public/foreign/structs.py b/xen/include/public/foreign/structs.py index 79eeab3b8e..6ecd1aa3dd 100644 --- a/xen/include/public/foreign/structs.py +++ b/xen/include/public/foreign/structs.py @@ -41,6 +41,8 @@ defines = [ "__i386__", "VGCF_failsafe_disables_events", "_VGCF_syscall_disables_events", "VGCF_syscall_disables_events", + "_VGCF_online", + "VGCF_online", # ia64 "VGCF_EXTRA_REGS", -- 2.30.2